module("wikisvnstorage", package.seeall)

require ("luasvn")

function starts_with (text, prefix) 
   if not prefix then return true end
   local preflen = prefix:len()
   return (    (text:len() >= preflen) 
	   and (text:sub(1, preflen) == prefix))
end



WikiSvnStorage = {

   dir = "",

   ----------------------------------------------------------------------------
   -- Creates a new "storage" object
   -- 
   -- @params dir the directory where the files will be stored
   ----------------------------------------------------------------------------


   new = function (self, dir)

      local obj = {dir = dir}

      setmetatable(obj, self)
      self.__index = self
      return obj         
   end,

   ----------------------------------------------------------------------------
   -- Return an object with a given id as a string.
   --
   -- @param version - the desired version of the object (defaults to current)
   -- @return the objct as a string
   ----------------------------------------------------------------------------

   load_object = function (self, id, version)
      
	  --This should work after change "version" to the number of the revision in the subversion repository
	  --local raw, err = luasvn.get_file_content (self.dir, id, version)
	   

	  --While "version" means the time a modification, this code works fine
	  local history, err = luasvn.get_file_history (self.dir, id)

	  if err then
		  return err
      end

	  for rev, name in pairs (history) do
	      local prop, err = luasvn.get_rev_proplist (self.dir, rev)
          for p, v in pairs (prop) do
			  if p == "svn:date" then
				  --This adjusts the svn:date, changing the "T" by a space. It also returns the micro seconds
				  local tmp = string.gsub (v, "T", " ")
				  if version == nil or version == tmp then
				      local raw, err = luasvn.get_file_content (self.dir, id, rev)
				      return raw
				  end
		      end
		  end
	  end
	  
	  return "Error: did not find any file with the supplied version!"
   end,

   ----------------------------------------------------------------------------
   -- Return true or false depending on whether the object with this id
   -- exists
   -- 
   -- @param id - an id of an object
   --
   ----------------------------------------------------------------------------

   object_exists = function (self, id)
	  if id then
		  local res, err = luasvn.file_exists (self.dir, id)
		  return res
	  else
	      return false 
	  end
   end,

   ----------------------------------------------------------------------------
   -- Lists all object ids
   -- exists
   -- 
   ----------------------------------------------------------------------------

   list_object_ids = function (self)
       local ids, err = luasvn.get_files (self.dir, "")  -- ids has the name of the file and the number of the last revision
	   local res = {}
	   for name, rev in pairs (ids) do
           table.insert (res, name)
	   end
   end,

   ----------------------------------------------------------------------------
   -- Saves the object with the current file stamp
   --
   -- @data the value to save
   ----------------------------------------------------------------------------

   save_object = function (self, id, data)
      local path = self.dir .. id

      if not self:object_exists (id) then
         local res, err = luasvn.create_file (self.dir, id)
      end
      
	  local res, err = luasvn.change_file (self.dir, id, data)
		
   end,

   ----------------------------------------------------------------------------
   -- Return the history of the object as a list of VERSIONS.
   -- The versions can be filtered by a prefix.
   --
   -- @param id the id of the object.
   ----------------------------------------------------------------------------

   get_object_history = function (self, id, prefix)
      prefix = prefix or ""
      
	  local res = {}

	  local history, err = luasvn.get_file_history (self.dir, id)

	  for rev, name in pairs (history) do
	      local prop, err = luasvn.get_rev_proplist (self.dir, rev)
          for p, v in pairs (prop) do
			  if p == "svn:date" then
				  --This adjusts the svn:date, changing the "T" by a space. It also returns the micro seconds
				  local tmp = string.gsub (v, "T", " ")
				  if starts_with (tmp, prefix) then
					  --This line is how it will be
					  --res [#res + 1] = {rev, v}
	  			      --This line works for while
					  res [#res + 1] = tmp
				  end
		      end
		  end
	  end

	  table.sort (res)

	  return res

   end
}


open = function(dir) return WikiSvnStorage:new(dir) end
